/* (PARI) R. J. Cano, Jun 20 2014; */

/* Implements the conversion from a GP matrix ("t_MAT") to a single GP list ("t_LIST")
*/
matx2Lst(M)={ 
  my(ans:list);
  ans=listcreate();
  for(i=1,#M[,1],
    for(j=1,#M[1,],
      listput(ans,M[i,j])
    )
  );
  ans
}

/* Makes a just-in-time offset correction.
*/
U(a,b)=if(b,b,a);

/* Check if [y,x] belongs or not to one of the diagonals for a squared matrix m*m.
 * 
 * ( Selectors: z=1 the main diagonal, z=0 the reversed diagonal )
*/
F(m,z,y,x)=if(z,(x==y),(m+1==x+y));

/* Implements the Steinhaus-Johnson-Trotter algorithm
 * returning the first "sum{k=1..n}(k!*k)" terms of A207324
 * in the form of a single GP list ("t_LIST").
 * 
 * When just=1 is used, it returns only the n-th matrix (n!*n items).
 * 
 * Warning: This is NOT exactly the same than A207324.
 * 
*/
likeA207324flattenedMatricesByRows(n,just=0)={
  my(z,m=1,q,B,a0:list,a1:list,a2:list);
  a0=matx2Lst(matrix(1,1,i,j,1));
  a2=listcreate();
  while(m<=n,
    B=matrix(m!,m);
    q=0;
    z=0;
    for(i=1,#B[,1],
      for(j=1,#B[1,],
	B[i,j]=m*F(m,z,U(m,i%m),j);
        q++;
      );
      if(q==m^2,q=0;z=!z);
    );
    a1=matx2Lst(B);
    q=1;
    for(s=1,m,
      for(p=1,#a0,
	while(a1[q]&&(q<#a1),q++);
	if(!a1[q],a1[q]=a0[p])
      )
    );
    a0=a1;
    for(k=1,#a0,
      listput(a2,a0[k])
    );
    m++;
  );
  if(just,a0,a2);
}

printPermutations(n)={
  my(Q=likeA207324flattenedMatricesByRows(n,1),u=0);
  for(i=1,n!,
    for(j=1,n,
        print1(Q[u++]);
    );
    print1("\n")
  )
}